package com.baor.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baor.dao.CustomerDao;
import com.baor.dao.EquipmentHolderOrdersDao;
import com.baor.dao.Equipment_holderDao;
import com.baor.dao.MonthlyDataDao;
import com.baor.domain.*;
import com.baor.service.Equipment_holderService;
import com.baor.util.R;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class Equipment_holderServiceImpl implements Equipment_holderService {
    @Autowired
    private Equipment_holderDao equipment_holderDao;
    @Autowired
    private CustomerDao customerDao;
    @Autowired
    private MonthlyDataDao monthlyDataDao;
    @Autowired
    private EquipmentHolderOrdersDao equipmentHolderOrdersDao;
    /**
     *{
     *     "pageIndex":1,
     *     "pageSize":10,
     *     "keyword": "阿豪"  手机号或姓名
     *     "startTime":"2025-09-28 09:35:19",开始时间
     *     "endTime":"2025-09-28 09:35:20",  结束时间
     *
     * }
     * @param params
     * @retur
     */
    @Override
    public R equipment_holderList(Map<String, Object> params) {
        Page page = new Page();
        page.setCurrent((int)params.get("pageIndex"));
        page.setSize((int)params.get("pageSize"));
        LambdaQueryWrapper<CustomerVO> wrapper = new LambdaQueryWrapper<>(CustomerVO.class)
                // 只选择 equipment_holder 表中实际存在的字段
                .select(CustomerVO::getId,
                        CustomerVO::getYesterdayEarning,
                        CustomerVO::getRealname,
                        CustomerVO::getPhone,
                        CustomerVO::getIdCard,
                        CustomerVO::getJoinTime,
                        CustomerVO::getMonthRevenue,
                        CustomerVO::getBalance,
                        CustomerVO::getDevicesNumber)
                .eq(CustomerVO::getIsHolder, 1);



        if (params.get("keyword") != null && !params.get("keyword").toString().trim().isEmpty()) {
            String keyword = params.get("keyword").toString().trim();
            wrapper.nested(wq -> wq
                    .like(CustomerVO::getRealname, keyword) 
                    .or()
                    .like(CustomerVO::getPhone, keyword)
            );

        }
        if (params.get("startTime") != null && !params.get("startTime").toString().trim().isEmpty()
                && params.get("endTime") != null && !params.get("endTime").toString().trim().isEmpty()) {
            String startTime = params.get("startTime").toString().trim();
            String endTime = params.get("endTime").toString().trim();

            wrapper.between(CustomerVO::getJoinTime, startTime, endTime);
        }
        IPage<CustomerVO> iPage = this.customerDao.selectPage(page,wrapper);
        Map<String, Object> map = new HashMap<>();
        map.put("totalSize", iPage.getTotal());
        map.put("List", iPage.getRecords());

        return R.ok(map);
    }

    /**
     * 删除设备持有者
     * @param params
     * @return
     */
    @Override
    public R equipment_holderDel(Map<String, Object> params) {
        return null;
    }
    /**   "id":6,
         "realname":"jinyong",
         "phone":"1231123123",
         "idCard":"123112323",
         "banlance":"45646",
         "isWithdraw":0,
         "remark":"asd"
     * 编辑设备持有者
     * @param params
     * @return
     */
    @Override
    public R updateHolderInfo(Map<String, Object> params) {
        // 1. 校验必要参数：ID 必须存在
        if (params == null || !params.containsKey("id") || !StringUtils.hasText(params.get("id").toString())) {
            return R.er("ID不能为空，无法更新！");
        }

        Long id = null;
        try {
            id = Long.parseLong(params.get("id").toString());
        } catch (NumberFormatException e) {
            return R.er("ID格式错误！");
        }

        // 2. 根据 ID 查询出要更新的对象
        // 这是一个好习惯，可以确保记录存在，并且可以获取未被前端修改的原始字段
        CustomerVO customerToUpdate = customerDao.selectById(id);
        if (customerToUpdate == null) {
            return R.er("该设备持有者不存在，无法更新！");
        }

        // 3. 从 params 中提取字段，并更新到对象中
        // 只更新前端传递了的、且不为空的字段
        if (params.containsKey("realname") ) {
            customerToUpdate.setRealname(params.get("realname").toString());
        }
        if (params.containsKey("phone")) {
            customerToUpdate.setPhone(params.get("phone").toString());
        }
        if (params.containsKey("idCard")) {
            customerToUpdate.setIdCard(params.get("idCard").toString());
        }
        // 你可以继续添加其他需要更新的字段，例如：
         if (params.containsKey("isWithdraw")) {
             customerToUpdate.setIsWithdraw((Integer) params.get("isWithdraw"));
         }
        if (params.containsKey("balance")) {
            customerToUpdate.setBalance((Integer) params.get("balance"));
        }
        if (params.containsKey("remark")) {
            customerToUpdate.setRemark((String) params.get("remark"));
        }

        // 4. 执行更新操作
        // updateById 方法会根据对象中的 id 字段来定位数据库记录，并更新其他所有字段
        int row = customerDao.updateById(customerToUpdate);

        // 5. 根据更新结果返回响应
        if (row > 0) {
            return R.ok("更新成功！");
        } else {
            // row == 0 可能是因为没有任何字段被修改，或者数据在查询之后被删除了
            return R.er("更新失败");
        }
    }

    /**
     *
     * {
     *     "id":2,
     *     "realname":"asd",
     *     "phone":"asd",
     *     "idCard":"asd",
     *     "balance":100,余额
     *     "changeBalance":200,  变更金额
     *     "changeType":0,  0增加 1 减少金额
     *     "remark":"asd"  备注
     *
     * }
     * 余额变更
     * @param params
     * @return
     */
    @Override
    public R updateBanlance(Map<String, Object> params) {
        // 1. 校验必要参数：ID 必须存在
        if (params == null || !params.containsKey("id") || !StringUtils.hasText(params.get("id").toString())) {
            return R.er("ID不能为空，无法更新！");
        }

        Long id = null;
        try {
            id = Long.parseLong(params.get("id").toString());
        } catch (NumberFormatException e) {
            return R.er("ID格式错误！");
        }

        // 2. 根据 ID 查询出要更新的对象
        // 这是一个好习惯，可以确保记录存在，并且可以获取未被前端修改的原始字段
        CustomerVO customerToUpdate = customerDao.selectById(id);
        if (customerToUpdate == null) {
            return R.er("该设备持有者不存在");
        }

        // 3. 从 params 中提取字段，并更新到对象中
        // 只更新前端传递了的、且不为空的字段
        if (params.containsKey("realname") ) {
            customerToUpdate.setRealname(params.get("realname").toString());
        }
        if (params.containsKey("phone")) {
            customerToUpdate.setPhone(params.get("phone").toString());
        }
        if (params.containsKey("idCard")) {
            customerToUpdate.setIdCard(params.get("idCard").toString());
        }

        if (params.containsKey("balance") && params.containsKey("changeBalance") && params.containsKey("changeType")) {
            // 1. 获取参数并进行类型转换
            Integer changeType = null;
            Integer changeBalance = null;
            Integer balance = null;
            try {
                // 转换操作类型（0=加，1=减）
                changeType = (Integer) params.get("changeType");
                // 转换变动金额（具体的数值，如50、100）
                changeBalance = (Integer) params.get("changeBalance");
                // 转换当前余额
                balance = (Integer) params.get("balance");
            } catch (Exception e) {
                return R.er("参数格式错误，请检查操作类型或金额是否为有效数字");
            }

            // 2. 校验参数有效性
            if (changeType == null || changeBalance == null || balance == null) {
                return R.er("操作类型、变动金额和当前余额不能为空");
            }
            // 校验操作类型只能是0或1
            if (changeType != 0 && changeType != 1) {
                return R.er("操作类型无效，只能是0（加）或1（减）");
            }
            // 校验变动金额不能为负数
            if (changeBalance < 0) {
                return R.er("变动金额不能为负数");
            }
            // 校验减法时余额是否充足
            if (changeType == 1 && balance < changeBalance) {
                return R.er("余额不足，当前余额：" + balance + "，需扣除：" + changeBalance);
            }

            // 3. 根据操作类型执行加减运算
            int newBalance;
            if (changeType == 0) {
                // 加法：当前余额 + 变动金额
                newBalance = balance + changeBalance;
                customerToUpdate.setBalance(newBalance);
            }
            if (changeType == 1)  {
                // 减法：当前余额 - 变动金额
                newBalance = balance - changeBalance;
                customerToUpdate.setBalance(newBalance);
            }

            // 4. 设置新余额

        }
        if (params.containsKey("remark")) {
            customerToUpdate.setRemark((String) params.get("remark"));
        }

        // 4. 执行更新操作
        // updateById 方法会根据对象中的 id 字段来定位数据库记录，并更新其他所有字段
        int row = customerDao.updateById(customerToUpdate);

        // 5. 根据更新结果返回响应
        if (row > 0) {
            return R.ok("更新成功！");
        } else {
            // row == 0 可能是因为没有任何字段被修改，或者数据在查询之后被删除了
            return R.er("更新失败");
        }
    }

    @Override

    public R addEquipmentHolder(Map<String, Object> params) {

        CustomerVO customer = new CustomerVO();

        if (params.containsKey("realname") ) {
            customer.setRealname(params.get("realname").toString());
        }
        if (params.containsKey("phone") ) {
            customer.setPhone(params.get("phone").toString());
        }
        if (params.containsKey("idCard") ) {
            customer.setIdCard(params.get("idCard").toString());
        }
        if (params.containsKey("balance") ) {
            customer.setBalance(Integer.parseInt(params.get("balance").toString()));
        }
        if (params.containsKey("isWithdraw") ) {
            customer.setIsWithdraw(Integer.parseInt(params.get("isWithdraw").toString()));
        }
        customer.setIsHolder(1);
        int insert = this.customerDao.insert(customer);
        Equipment_holder_orders equipment_holder_orders = new Equipment_holder_orders();
        equipment_holder_orders.setRole(0);
        equipment_holder_orders.setUsername(customer.getRealname());
        equipment_holder_orders.setPhone(customer.getPhone());
        equipment_holder_orders.setMoney(BigDecimal.valueOf(18999));
        equipment_holder_orders.setRemarks("设备购买费用");
        equipment_holder_orders.setPayTime(String.valueOf(LocalDateTime.now()));
        equipment_holder_orders.setPayMethod("后台添加");
        //订单编号
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String workOrderNo = "XQ" + LocalDateTime.now().format(formatter);
        equipment_holder_orders.setOrderCode(workOrderNo);
        equipmentHolderOrdersDao.insert(equipment_holder_orders);
        return insert > 0 ? R.ok("插入成功+ 新数据的id"+customer.getId()) : R.er("错误") ;
    }
//历史账单
    @Override
    public R historicalBills(Map<String, Object> params) {
            // 1. 参数校验
            if (params == null || !params.containsKey("id") || StringUtils.isEmpty(params.get("id"))) {
                return R.er("持有者ID不能为空");
            }

            Integer holderId;
            try {
                // 转换持有者ID（根据实际ID类型调整，此处假设为Integer）
                holderId = Integer.parseInt(params.get("id").toString().trim());
            } catch (NumberFormatException e) {
                return R.er("持有者ID格式错误，请输入有效数字");
            }

            // 2. 构建查询条件（使用MPJLambdaWrapper进行关联查询或单表查询）
            MPJLambdaWrapper<MonthlyDataVo> queryWrapper = new MPJLambdaWrapper<MonthlyDataVo>()
                    // 选择需要返回的字段（建议明确指定，而非selectAll()，避免冗余字段）
                    .select(
                            MonthlyDataVo::getId,
                            MonthlyDataVo::getHolderId,
                            MonthlyDataVo::getRealname,
                            MonthlyDataVo::getDevicesNumber,
                            MonthlyDataVo::getLastMonthInfo,
                            MonthlyDataVo::getBalance,
                            MonthlyDataVo::getCreateTime
                    )
                    // 关联持有者ID
                    .eq(MonthlyDataVo::getHolderId, holderId);

            // 3. 支持分页查询（可选，根据需求添加）
            Page<MonthlyDataVo> page = null;
            if (params.containsKey("pageIndex") && params.containsKey("pageSize")) {
                try {
                    int pageIndex = Integer.parseInt(params.get("pageIndex").toString().trim());
                    int pageSize = Integer.parseInt(params.get("pageSize").toString().trim());
                    page = new Page<>(pageIndex, pageSize);
                } catch (NumberFormatException e) {
                    return R.er("分页参数格式错误");
                }
            }

            // 4. 执行查询
            List<MonthlyDataVo> monthlyDataList;
            long total = 0;
            if (page != null) {
                IPage<MonthlyDataVo> iPage = monthlyDataDao.selectPage(page, queryWrapper);
                monthlyDataList = iPage.getRecords();
                total = iPage.getTotal();
            } else {
                monthlyDataList = monthlyDataDao.selectList(queryWrapper);
                total = monthlyDataList.size();
            }

            // 5. 封装返回结果
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("totalSize", total);
            resultMap.put("list", monthlyDataList);

            return R.ok(resultMap);
        }

    @Override
    @Transactional
    public R addEquipment(Map<String, Object> params) {
        int id = Integer.parseInt(params.get("id").toString().trim());
        String realname = params.get("realname").toString().trim();
        String phone = params.get("phone").toString().trim();
        String orginzation = params.get("orginzation").toString().trim();
        Integer inviterId = Integer.parseInt(params.get("inviterId").toString().trim());
        Integer num = Integer.parseInt(params.get("num").toString().trim());
        CustomerVO customer = new CustomerVO();
        customer.setId(id);
        customer.setRealname(realname);
        customer.setPhone(phone);
        customer.setOrganization(orginzation);
        customer.setInviterId(inviterId);
        Integer num1 = this.customerDao.selectById(id).getNums();
        Integer newNum = num + num1;
        customer.setNums(newNum);
        this.customerDao.updateById(customer);
        Integer equipmentId = Integer.parseInt(params.get("equipmentId").toString().trim());
        Integer rent = Integer.parseInt(params.get("rent").toString().trim());
        String bankName = params.get("bankName").toString().trim();
        String bank = params.get("bank").toString().trim();
        String contractStart = params.get("contractStart").toString().trim();
        String contractEnd = params.get("contractEnd").toString().trim();
        String bankId = params.get("bankId").toString().trim();
        String bankBranch = params.get("bankBranch").toString().trim();
        String x = params.get("x").toString().trim();
        String y = params.get("y").toString().trim();
        BigDecimal price = new BigDecimal(params.get("price").toString().trim());
        EquipmentHolder equipmentHolder = new EquipmentHolder();
        equipmentHolder.setEquipmentId(equipmentId);
        equipmentHolder.setCustomerId(id);
        equipmentHolder.setRent(rent);
        equipmentHolder.setBankId(bankId);
        equipmentHolder.setBankBranch(bankBranch);
        equipmentHolder.setContractStart(contractStart);
        equipmentHolder.setContractEnd(contractEnd);
        equipmentHolder.setBank(bank);
        equipmentHolder.setBankName(bankName);
        equipmentHolder.setX(x);
        equipmentHolder.setY(y);
        equipmentHolder.setPrice(price);
        this.equipment_holderDao.insert(equipmentHolder);
        return R.ok();
    }

    @Override
    public R deviceList(Map<String, Object> params) {
        long pageIndex = params.get("pageIndex") != null ? Long.parseLong(params.get("pageIndex").toString()) : 1;
        long pageSize = params.get("pageSize") != null ? Long.parseLong(params.get("pageSize").toString()) : 10;
        long offset = (pageIndex - 1) * pageSize;

        // 设置分页参数
        Map<String, Object> queryParams = new HashMap<>();
        queryParams.put("keyword", params.get("keyword"));
        queryParams.put("offset", offset);
        queryParams.put("pageSize", pageSize);

        // 查询数据
        List<CustomerEquipmentVO> list = this.customerDao.selectCustomerEquipmentListManual(queryParams);
        // 查询总数
        Long total = this.customerDao.selectCustomerEquipmentCount(queryParams);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("totalSize", total);
        resultMap.put("list", list);
        return R.ok(resultMap);

    }

    @Override
    public R updateDevice(EquipmentHolder equipmentHolder) {

            // 参数验证
            if (equipmentHolder.getId() == null) {
                return R.er("ID不能为空");
            }

            //修改customer的公司
                EquipmentHolder equipmentHolder1 = this.equipment_holderDao.selectById(equipmentHolder.getId());
                Integer customerId = equipmentHolder1.getCustomerId();
                CustomerVO customerVO = this.customerDao.selectById(customerId);
                String organization = equipmentHolder.getOrganization().toString();
                customerVO.setOrganization(organization);
                this.customerDao.updateById(customerVO);

            // 执行更新
            int success = equipment_holderDao.updateById(equipmentHolder);
            return success > 0 ? R.ok("更新成功") : R.er("更新失败");


    }

    @Override
    public R changeHolder(EquipmentHolder equipmentHolder) {
        // 参数验证
        if (equipmentHolder.getId() == null) {
            return R.er("ID不能为空");
        }



        //根据id查customerID
            EquipmentHolder equipmentHolder1 = this.equipment_holderDao.selectById(equipmentHolder.getId());
            Integer customerId = equipmentHolder1.getCustomerId();
        //修改customer的公司
            CustomerVO customerVO = this.customerDao.selectById(customerId);
            String organization = equipmentHolder.getOrganization().toString();
            customerVO.setOrganization(organization);
            this.customerDao.updateById(customerVO);



        // 执行更新
        int success = equipment_holderDao.updateById(equipmentHolder);
        return success > 0 ? R.ok("更新成功") : R.er("更新失败");
    }


}



